#include <stdio.h>
#include "mmpf_system.h"
#include "lib_retina.h"
#include "hdm_ctl.h"
#include "text_ctl.h"
#include "mmpf_sensor.h"

extern	MMP_ULONG	m_glISPBufferStartAddr;

#if DRAM_SIZE <= 2
#if (MotionDetection == 1)
    MMP_ULONG	AEAcc_Buffer[9];
#else
    MMP_UBYTE	AEAcc_Buffer[36];
#endif
    MMP_UBYTE	AWBAcc_Buffer[128];
    MMP_UBYTE	AFAcc_Buffer[200]; //Truman120919 This buffer is required no matter AF is on or off.
                                   //It seems that the IQ table does not enable/disable HW ACC write.
    MMP_UBYTE	HistAcc_Buffer[512];
    MMP_UBYTE   FlickerAcc_Buffer[128];
#else
    MMP_ULONG	AEAcc_Buffer[256];
    MMP_ULONG	AWBAcc_Buffer[256* 5];
    MMP_ULONG	AFAcc_Buffer[60];
    MMP_ULONG	HistAcc_Buffer[128];
    MMP_ULONG   FlickerAcc_Buffer[32];
#endif

#if (IQ_TABLE_LOAD_FROM_FLASH == 0)
extern ISP_UINT8 Sensor_IQ_CompressedText[];
#endif
/*
#pragma arm section code = "IQ_PlainText", rwdata = "IQ_PlainText",  zidata = "IQ_PlainText"
//these 2 array are used for plain file size. DstAddr[] needs sizes of these 2 arrays.
//these 2 array should be removed automatically since it is not referenced.

#if BIND_SENSOR_OV5647 == 1
    const ISP_UINT8 PlainIQ1[] = {
    #include "isp_8451_iq_data_v2_OV5647.xls.iq.txt"
    };
    #elif BIND_SENSOR_OV5647 == 2
    const ISP_UINT8 PlainIQ2[] = {
    #include "isp_8451_iq_data_v2_OV5647.xls.iq.txt"
    };
#endif
#if BIND_SENSOR_OV5650 == 1
    const ISP_UINT8 PlainIQ1[] = {
    #include "isp_8451_iq_data_v2_OV5650.xls.iq.txt"
    };
    #elif BIND_SENSOR_OV5650 == 2
    const ISP_UINT8 PlainIQ2[] = {
    #include "isp_8451_iq_data_v2_OV5650.xls.iq.txt"
    };
#endif
#if BIND_SENSOR_OV9726 == 1
    const ISP_UINT8 PlainIQ1[] = {
    #if (CUSTOMER == PNS) || (CUSTOMER == IPC)
        #include "isp_8451_iq_data_v2_OV9726_PNS.xls.iq.txt"
    #else
        #include "isp_8451_iq_data_v2_OV9726_ASU.xls.iq.txt"
    #endif
    };
    #elif BIND_SENSOR_OV9726 == 2
    const ISP_UINT8 PlainIQ2[] = {
    #if CUSTOMER == ASU
        #include "isp_8451_iq_data_v2_OV9726_asu.xls.iq.txt"
    #endif
    };
#endif
#if BIND_SENSOR_OV9710 == 1
    const ISP_UINT8 PlainIQ1[] = {
    #include "isp_8451_iq_data_v2_OV9710.xls.iq.txt"
    };
    #elif BIND_SENSOR_OV9710 == 2
    const ISP_UINT8 PlainIQ2[] = {
    #include "isp_8451_iq_data_v2_OV9710.xls.iq.txt"
    };
#endif
#if BIND_SENSOR_MT9D111 == 1
    const ISP_UINT8 PlainIQ1[] = {
    #include "isp_8451_iq_data_v2_mt9d111.xls.iq.txt"
    };
#endif
#if BIND_SENSOR_AR0330 == 1
    const ISP_UINT8 PlainIQ1[] = {
    #include "isp_8451_iq_data_v2_AR0330.xls.iq.txt"
    };
#endif
#if BIND_SENSOR_AR0832E == 1
    const ISP_UINT8 PlainIQ1[] = {
    #include "isp_8451_iq_data_v2_AR0832E.xls.iq.txt"
    };
#endif
#if BIND_SENSOR_HM1375 == 1
    const ISP_UINT8 PlainIQ1[] = {
    #include "isp_8451_iq_data_v2_HM1375.xls.iq.txt"
    };
#endif

#pragma arm section code, rwdata, zidata

//__align(4) ISP_UINT8 DstAddr[64*1024];
#if TOTAL_SENSOR_NUMBER == 2
__align(4) ISP_UINT8 DstAddr[sizeof(PlainIQ1)>sizeof(PlainIQ2)?sizeof(PlainIQ1):sizeof(PlainIQ2)];
#else
__align(4) ISP_UINT8 DstAddr[sizeof(PlainIQ1)];
#endif

__align(4) ISP_UINT8 TmpBufAddr[1024];
ISP_UINT32 glPlainIqSize = sizeof(DstAddr);//used for export run-time size
*/
void ISP_HDM_IF_CALI_GetData(void)
{
}

ISP_UINT8 ISP_HDM_IF_IQ_IsApicalClkOff(void)
{
	return 1;
}

ISP_UINT32 ISP_HDM_IF_LIB_GetBufAddr(ISP_BUFFER_CLASS buf_class, ISP_UINT32 buf_size, ISP_BUFFER_TYPE buf_type)
{
	ISP_UINT32 addr = 0;
	ISP_UINT32 cached_size = 0;
	char str[8];
	snprintf(str, 7, "ISP%d", buf_class);
	if (buf_type == ISP_BUFFER_TYPE_NONCACHEABLE) {
        //accumulate all the needed ISP size.
        //assume this is only be run ONCE!
        //if (ISP_BUFFER_CLASS_MEMOPR_LS == buf_class) {
        //    int ask_Eric;//it reports 2 K only!!!
        //    buf_size = 3 * 1024;
        //}
        addr = (ISP_UINT32)MMPF_SYS_AllocFB(str, buf_size, 32);
        MMPF_Sensor_SetBufferSize(MMPF_Sensor_CalculateBufferSize() + ((buf_size + 31) & ((MMP_ULONG)-32)));
	} else {
	    //dbg_printf(3, "---> %s SW: %d\r\n", str, buf_size);
	}

	switch (buf_class) {
	case ISP_BUFFER_CLASS_IQ_BIN_SRC:
    #if (IQ_TABLE_LOAD_FROM_FLASH == 0)
		addr = 0;//(ISP_UINT32)Sensor_IQ_CompressedText;
	#else
#if DRAM_SIZE > 2
		addr = m_glISPBufferStartAddr + ISP_BUFFER_SIZE;
#else
		addr = FW_DOWNLOAD_BUFFER;
#endif
    #endif
		break;
	case ISP_BUFFER_CLASS_IQ_BIN_DST:
		addr = (ISP_UINT32)Sensor_IQ_CompressedText;//(ISP_UINT32)DstAddr;//(ISP_UINT32)Sensor_IQ_CompressedText;// 
		break;
	case ISP_BUFFER_CLASS_IQ_BIN_TMP:
		addr = 0;//(ISP_UINT32)TmpBufAddr;
		break;
	case ISP_BUFFER_CLASS_MEMOPR_IQ:
		//addr = IQ_BANK_ADDR;
		break;
	case ISP_BUFFER_CLASS_MEMOPR_LS:
		//addr = LS_BANK_ADDR;
		break;
	case ISP_BUFFER_CLASS_MEMOPR_CS:
		//addr = CS_BANK_ADDR;
		break;
	case ISP_BUFFER_CLASS_AE_HW:
	#if DRAM_SIZE > 2
		addr = (m_glISPBufferStartAddr + ISP_AWB_BUF_SIZE);
    #endif
		break;
	case ISP_BUFFER_CLASS_AE_SW:
		addr = (ISP_UINT32)AEAcc_Buffer;
		cached_size = sizeof(AEAcc_Buffer);
		break;
	case ISP_BUFFER_CLASS_AF_HW:
	#if DRAM_SIZE > 2
		addr = (m_glISPBufferStartAddr + ISP_AWB_BUF_SIZE + ISP_AE_BUF_SIZE);
    #endif
		break;
	case ISP_BUFFER_CLASS_AF_SW:
		addr = (ISP_UINT32)AFAcc_Buffer;
	    //Truman@120919 Check with Eric Chuang. AF should be able to released if no AF is required.
	    //But after experiment it would overwrite some other buffer and cause IQ abnormal.
		cached_size = sizeof(AFAcc_Buffer);
		break;
	case ISP_BUFFER_CLASS_AWB_HW:
	#if DRAM_SIZE > 2
		addr = m_glISPBufferStartAddr;
	#endif
		break;
	case ISP_BUFFER_CLASS_AWB_SW:
		addr = (ISP_UINT32)AWBAcc_Buffer;
		cached_size = sizeof(AWBAcc_Buffer);
		break;
	case ISP_BUFFER_CLASS_FLICKER_HW:
	#if DRAM_SIZE > 2
		addr = (m_glISPBufferStartAddr + ISP_AWB_BUF_SIZE + ISP_AE_BUF_SIZE + ISP_AF_BUF_SIZE + ISP_DFT_BUF_SIZE + ISP_HIST_BUF_SIZE);
	#endif
		break;
	case ISP_BUFFER_CLASS_FLICKER_SW:
		addr = (ISP_UINT32)FlickerAcc_Buffer;
		cached_size = sizeof(FlickerAcc_Buffer);
		break;
	case ISP_BUFFER_CLASS_HIST_HW:
	#if DRAM_SIZE > 2
		addr = (m_glISPBufferStartAddr + ISP_AWB_BUF_SIZE + ISP_AE_BUF_SIZE + ISP_AF_BUF_SIZE + ISP_DFT_BUF_SIZE);
	#endif
		break;
	case ISP_BUFFER_CLASS_HIST_SW:
		addr = (ISP_UINT32)HistAcc_Buffer;
		cached_size = sizeof(HistAcc_Buffer);
		break;
	default:
		break;
	}

    if (cached_size) {
        //need to check internal buffer size.(ZI) against requested size.
        if (buf_size != cached_size) {
            dbg_printf(3, "%d requested but %d provided.\r\n", buf_size, cached_size);
            if (buf_size > cached_size) {
                //critical error.
                while(1);
            }
        }
        else {
        //    DBG_S(3, "MATCH\r\n");
        }
    }

	return addr;
}

ISP_UINT32 ISP_HDM_IF_LIB_RamAddrV2P(ISP_UINT32 addr) {
      return addr;
}
ISP_UINT32 ISP_HDM_IF_LIB_RamAddrP2V(ISP_UINT32 addr) {
      return addr;
}
ISP_UINT32 ISP_HDM_IF_LIB_OprAddrV2P(ISP_UINT32 addr) {
      return addr;
}
ISP_UINT32 ISP_HDM_IF_LIB_OprAddrP2V(ISP_UINT32 addr) {
      return addr;
}

#if DRAW_TEXT_FEATURE_EN
ISP_INT8 MultiShading;
ISP_INT16 CCM_PRT[9];

void VR_PrintStringOnPreview(void)
{
	if(gDrawTextEn){
		
	#if 1
	//	_sprintf(gDrawTextBuf, "AE  : Shutter=%x cA(%x), AGain=%x, DGain=%x", (ISP_UINT32)gAEConfig.Shutter, (ISP_UINT32)gAEConfig.BackupcAGain, (ISP_UINT32)gAEConfig.AGain, (ISP_UINT32)gAEConfig.DGain);
		_sprintf((char*)gDrawTextBuf, (char*)"AE  : Shutter=%x(Base: %d) (%d)FPS, AGain=%x", (MMP_ULONG)ISP_IF_AE_GetShutter(), (MMP_ULONG)ISP_IF_AE_GetShutterBase(), (MMP_ULONG)ISP_IF_AE_GetRealFPS(), (MMP_ULONG)ISP_IF_AE_GetGain());
		VR_PrintString(gDrawTextBuf,  10, 0, 0xFC00, 0x0000);
		_sprintf((char*)gDrawTextBuf, (char*)"EV:%x, AE  : AvgLum=%x",(MMP_ULONG)ISP_IF_AE_GetDbgData(0), (MMP_ULONG)ISP_IF_AE_GetDbgData(1));
		VR_PrintString(gDrawTextBuf,  30, 0, 0xFC00, 0x0000);
		_sprintf((char*)gDrawTextBuf, (char*)"DBG8:%x, %x, %x",(MMP_ULONG)ISP_IF_IQ_GetID(ISP_IQ_CHECK_CLASS_COLORTEMP),  (MMP_ULONG)ISP_IF_IQ_GetID(ISP_IQ_CHECK_CLASS_GAIN),  (MMP_ULONG)ISP_IF_IQ_GetID(ISP_IQ_CHECK_CLASS_ENERGY));
		VR_PrintString(gDrawTextBuf,  80, 0, 0xFC00, 0x0000);

	//	_sprintf(gDrawTextBuf, "AE  : MaxSht=%x", (ISP_UINT32)gAEConfig.Ctl_CurvePoints[gAEConfig.Ctl_CurvePoints_MaxIdx].Shutter);
	//	VR_PrintString(gDrawTextBuf,  30, 10, 0xFFFF, 0x0000);
	//	_sprintf(gDrawTextBuf, "AE  : ExpoIdx=%x", (ISP_UINT32)gAEConfig.ExpoIdx);
	//	VR_PrintString(gDrawTextBuf,  50, 10, 0xFFFF, 0x0000);
	#endif

	#if 1
		_sprintf((char*)gDrawTextBuf, (char*)"AWB : Mode=%x, GainR=%d, GainGr=%d, GainB=%d,  ColorTemp=%d, BackB=%x ", (MMP_ULONG)ISP_IF_AWB_GetMode(), (MMP_ULONG)ISP_IF_AWB_GetGainR()/8, (MMP_ULONG)ISP_IF_AWB_GetGainG()/8, (MMP_ULONG)ISP_IF_AWB_GetGainB()/8, (MMP_ULONG)ISP_IF_AWB_GetColorTemp(),(MMP_LONG)ISP_IF_AWB_GetDbgData(0));
		VR_PrintString(gDrawTextBuf,  0, 0, 0xFC00, 0x0000);
		_sprintf((char*)gDrawTextBuf, (char*)"AWB_rb_id = (%d,%d) Energy=%x, Lux=%d, BackB=%x", (MMP_LONG)ISP_IF_AWB_GetDbgData(8), (MMP_LONG)ISP_IF_AWB_GetDbgData(9), (MMP_LONG)ISP_IF_AE_GetDbgData(30), (MMP_ULONG)ISP_IF_AE_GetLightCond(),(MMP_LONG)ISP_IF_AWB_GetDbgData(0));
		VR_PrintString(gDrawTextBuf,  20, 0, 0xFC00, 0x0000);
		_sprintf((char*)gDrawTextBuf, (char*)"%x, %x,", (MMP_LONG)ISP_IF_AE_GetDbgData(28), (MMP_LONG)ISP_IF_AE_GetDbgData(29));
		VR_PrintString(gDrawTextBuf,  60, 0, 0xFC00, 0x0000);
		
	//	_sprintf(gDrawTextBuf, "CCM %d %d %d", (ISP_INT32)CCM_PRT[0], (ISP_INT32)CCM_PRT[1], (ISP_INT32)CCM_PRT[2]);
	//	VR_PrintString(gDrawTextBuf,  50, 0, 0xFC00, 0x0000);
	//	_sprintf(gDrawTextBuf, "CCM %d %d %d", (ISP_INT32)CCM_PRT[3], (ISP_INT32)CCM_PRT[4], (ISP_INT32)CCM_PRT[5]);
	//	VR_PrintString(gDrawTextBuf,  60, 0, 0xFC00, 0x0000);
	//	_sprintf(gDrawTextBuf, "CCM %d %d %d", (ISP_INT32)CCM_PRT[6], (ISP_INT32)CCM_PRT[7], (ISP_INT32)CCM_PRT[8]);
	//	VR_PrintString(gDrawTextBuf,  70, 0, 0xFC00, 0x0000);
	#endif

	#if 1
		//_sprintf(gDrawTextBuf, "AF  : AFPos=%x, AFMODE=%x", (ISP_UINT32)gAFConfig.AFPos, (ISP_UINT32)gISPConfig.AutoFocusMode);
	//	_sprintf(gDrawTextBuf, "AF  : AFPos=%x, AFMODE=%x", (ISP_UINT32)ISP_IF_AF_GetPos(), (ISP_UINT32)ISP_IF_AF_GetDbgData(0));
	//	VR_PrintString(gDrawTextBuf,  40, 0, 0xFC00, 0x0000);

		{
			ISP_UINT32 *dbgPtr = (ISP_UINT32 *)ISP_IF_AF_GetDbgDataPtr();
			_sprintf((char*)gDrawTextBuf, (char*)"AF  : AFPos=%x, dbg=%x %x %x", (MMP_ULONG)ISP_IF_AF_GetPos(10), (MMP_ULONG)dbgPtr[0], (MMP_ULONG)dbgPtr[1], (MMP_ULONG)dbgPtr[2]);
			VR_PrintString(gDrawTextBuf,  40, 0, 0xFC00, 0x0000);
		}
		//_sprintf(gDrawTextBuf, "AF  : MotorState=%x", (ISP_UINT32)gAFConfig.MotorState);
		//VR_PrintString(gDrawTextBuf,  60, 10, 0xFFFF, 0x0000);
		//_sprintf(gDrawTextBuf, "AF  : AFACC=%x(%x)", (ISP_UINT32)gAFConfig.AFAcc[30], (ISP_UINT32)(*(ISP_UINT32*)(m_ulAFBufStartAddr+4*30)));
		//VR_PrintString(gDrawTextBuf,  60, 10, 0xFFFF, 0x0000);

	#endif
	 }
}
#endif

